"""
企业级金融数据MCP服务系统 - 宏观经济数据模型
提供完整的宏观经济相关数据SQLAlchemy ORM模型定义
"""

from datetime import datetime, date
from decimal import Decimal
from typing import Optional, Dict, Any
from sqlalchemy import String, DateTime, Date, Boolean, Integer, Numeric, Text, Index, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.dialects.postgresql import JSONB

from .base import BaseFinancialModel, DataVersionMixin, SyncStatusMixin, PartitionMixin


class MacroEconomicIndicator(BaseFinancialModel, PartitionMixin):
    """
    宏观经济指标数据模型
    存储各类宏观经济指标数据，如GDP、CPI、PPI、PMI等
    """
    __tablename__ = "macro_economic_indicator"
    
    # 指标代码
    indicator_code: Mapped[str] = mapped_column(String(50), nullable=False, comment="指标代码")
    
    # 指标名称
    indicator_name: Mapped[str] = mapped_column(String(200), nullable=False, comment="指标名称")
    
    # 统计期间
    period: Mapped[date] = mapped_column(Date, nullable=False, comment="统计期间")
    
    # 指标值
    value: Mapped[Optional[Decimal]] = mapped_column(Numeric(20, 6), nullable=True, comment="指标值")
    
    # 同比增长率(%)
    yoy_growth: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 4), nullable=True, comment="同比增长率(%)")
    
    # 环比增长率(%)
    mom_growth: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 4), nullable=True, comment="环比增长率(%)")
    
    # 累计值
    cumulative_value: Mapped[Optional[Decimal]] = mapped_column(Numeric(20, 6), nullable=True, comment="累计值")
    
    # 累计同比增长率(%)
    cumulative_yoy: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 4), nullable=True, comment="累计同比增长率(%)")
    
    # 单位
    unit: Mapped[Optional[str]] = mapped_column(String(50), nullable=True, comment="单位")
    
    # 频率：月度, 季度, 年度
    frequency: Mapped[str] = mapped_column(String(20), nullable=False, comment="频率")
    
    # 地区代码
    region_code: Mapped[Optional[str]] = mapped_column(String(20), nullable=True, comment="地区代码")
    
    # 地区名称
    region_name: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, comment="地区名称")
    
    # 行业代码
    industry_code: Mapped[Optional[str]] = mapped_column(String(20), nullable=True, comment="行业代码")
    
    # 行业名称
    industry_name: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, comment="行业名称")
    
    # 发布机构
    publisher: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, comment="发布机构")
    
    # 发布日期
    publish_date: Mapped[Optional[date]] = mapped_column(Date, nullable=True, comment="发布日期")
    
    # 备注
    remark: Mapped[Optional[str]] = mapped_column(Text, nullable=True, comment="备注")
    
    __table_args__ = (
        UniqueConstraint('indicator_code', 'period', 'region_code', 'industry_code', 
                        name='uk_macro_indicator_code_period_region_industry'),
        Index('idx_macro_indicator_code', 'indicator_code'),
        Index('idx_macro_indicator_period', 'period'),
        Index('idx_macro_indicator_name', 'indicator_name'),
        Index('idx_macro_indicator_frequency', 'frequency'),
        Index('idx_macro_indicator_region', 'region_code'),
        Index('idx_macro_indicator_industry', 'industry_code'),
        Index('idx_macro_indicator_publisher', 'publisher'),
        Index('idx_macro_indicator_publish_date', 'publish_date'),
        # 分区索引
        Index('idx_macro_indicator_partition_date', 'partition_date'),
    )
    
    def __repr__(self) -> str:
        return f"<MacroEconomicIndicator(indicator_code={self.indicator_code}, period={self.period}, value={self.value})>"


class MonetaryPolicy(BaseFinancialModel, PartitionMixin):
    """
    货币政策数据模型
    存储央行货币政策相关数据，如利率、存款准备金率等
    """
    __tablename__ = "monetary_policy"
    
    # 政策类型：利率, 存款准备金率, 公开市场操作等
    policy_type: Mapped[str] = mapped_column(String(50), nullable=False, comment="政策类型")
    
    # 政策工具：基准利率, 存款准备金率, 逆回购, 正回购, MLF, SLF等
    policy_tool: Mapped[str] = mapped_column(String(50), nullable=False, comment="政策工具")
    
    # 生效日期
    effective_date: Mapped[date] = mapped_column(Date, nullable=False, comment="生效日期")
    
    # 调整前数值
    before_value: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 6), nullable=True, comment="调整前数值")
    
    # 调整后数值
    after_value: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 6), nullable=True, comment="调整后数值")
    
    # 调整幅度
    adjustment: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 6), nullable=True, comment="调整幅度")
    
    # 期限（天）
    term_days: Mapped[Optional[Integer]] = mapped_column(Integer, nullable=True, comment="期限(天)")
    
    # 操作量（亿元）
    operation_amount: Mapped[Optional[Decimal]] = mapped_column(Numeric(20, 4), nullable=True, comment="操作量(亿元)")
    
    # 单位
    unit: Mapped[Optional[str]] = mapped_column(String(20), nullable=True, comment="单位")
    
    # 政策描述
    policy_description: Mapped[Optional[str]] = mapped_column(Text, nullable=True, comment="政策描述")
    
    # 发布机构
    publisher: Mapped[str] = mapped_column(String(100), nullable=False, default="中国人民银行", comment="发布机构")
    
    # 发布日期
    publish_date: Mapped[Optional[date]] = mapped_column(Date, nullable=True, comment="发布日期")
    
    __table_args__ = (
        UniqueConstraint('policy_type', 'policy_tool', 'effective_date', 'term_days', 
                        name='uk_monetary_policy_type_tool_date_term'),
        Index('idx_monetary_policy_type', 'policy_type'),
        Index('idx_monetary_policy_tool', 'policy_tool'),
        Index('idx_monetary_policy_effective_date', 'effective_date'),
        Index('idx_monetary_policy_publish_date', 'publish_date'),
        # 分区索引
        Index('idx_monetary_policy_partition_date', 'partition_date'),
    )
    
    def __repr__(self) -> str:
        return f"<MonetaryPolicy(policy_type={self.policy_type}, policy_tool={self.policy_tool}, effective_date={self.effective_date})>"


class FiscalData(BaseFinancialModel, PartitionMixin):
    """
    财政数据模型
    存储政府财政收支相关数据
    """
    __tablename__ = "fiscal_data"
    
    # 统计期间
    period: Mapped[date] = mapped_column(Date, nullable=False, comment="统计期间")
    
    # 数据类型：收入, 支出, 结余
    data_type: Mapped[str] = mapped_column(String(20), nullable=False, comment="数据类型")
    
    # 科目代码
    subject_code: Mapped[str] = mapped_column(String(50), nullable=False, comment="科目代码")
    
    # 科目名称
    subject_name: Mapped[str] = mapped_column(String(200), nullable=False, comment="科目名称")
    
    # 当期金额（亿元）
    current_amount: Mapped[Optional[Decimal]] = mapped_column(Numeric(20, 4), nullable=True, comment="当期金额(亿元)")
    
    # 累计金额（亿元）
    cumulative_amount: Mapped[Optional[Decimal]] = mapped_column(Numeric(20, 4), nullable=True, comment="累计金额(亿元)")
    
    # 同比增长率(%)
    yoy_growth: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 4), nullable=True, comment="同比增长率(%)")
    
    # 累计同比增长率(%)
    cumulative_yoy: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 4), nullable=True, comment="累计同比增长率(%)")
    
    # 占比(%)
    proportion: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 4), nullable=True, comment="占比(%)")
    
    # 级别：中央, 地方, 全国
    level: Mapped[str] = mapped_column(String(20), nullable=False, comment="级别")
    
    # 地区代码
    region_code: Mapped[Optional[str]] = mapped_column(String(20), nullable=True, comment="地区代码")
    
    # 地区名称
    region_name: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, comment="地区名称")
    
    # 频率：月度, 季度, 年度
    frequency: Mapped[str] = mapped_column(String(20), nullable=False, comment="频率")
    
    # 发布日期
    publish_date: Mapped[Optional[date]] = mapped_column(Date, nullable=True, comment="发布日期")
    
    __table_args__ = (
        UniqueConstraint('period', 'data_type', 'subject_code', 'level', 'region_code', 
                        name='uk_fiscal_data_period_type_subject_level_region'),
        Index('idx_fiscal_data_period', 'period'),
        Index('idx_fiscal_data_type', 'data_type'),
        Index('idx_fiscal_data_subject', 'subject_code'),
        Index('idx_fiscal_data_level', 'level'),
        Index('idx_fiscal_data_region', 'region_code'),
        Index('idx_fiscal_data_frequency', 'frequency'),
        # 分区索引
        Index('idx_fiscal_data_partition_date', 'partition_date'),
    )
    
    def __repr__(self) -> str:
        return f"<FiscalData(period={self.period}, data_type={self.data_type}, subject_name={self.subject_name})>"


class TradeData(BaseFinancialModel, PartitionMixin):
    """
    贸易数据模型
    存储进出口贸易相关数据
    """
    __tablename__ = "trade_data"
    
    # 统计期间
    period: Mapped[date] = mapped_column(Date, nullable=False, comment="统计期间")
    
    # 贸易类型：进口, 出口, 贸易差额
    trade_type: Mapped[str] = mapped_column(String(20), nullable=False, comment="贸易类型")
    
    # 商品代码
    commodity_code: Mapped[Optional[str]] = mapped_column(String(50), nullable=True, comment="商品代码")
    
    # 商品名称
    commodity_name: Mapped[Optional[str]] = mapped_column(String(200), nullable=True, comment="商品名称")
    
    # 国家/地区代码
    country_code: Mapped[Optional[str]] = mapped_column(String(20), nullable=True, comment="国家/地区代码")
    
    # 国家/地区名称
    country_name: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, comment="国家/地区名称")
    
    # 金额（亿美元）
    amount_usd: Mapped[Optional[Decimal]] = mapped_column(Numeric(20, 4), nullable=True, comment="金额(亿美元)")
    
    # 金额（亿人民币）
    amount_cny: Mapped[Optional[Decimal]] = mapped_column(Numeric(20, 4), nullable=True, comment="金额(亿人民币)")
    
    # 数量
    quantity: Mapped[Optional[Decimal]] = mapped_column(Numeric(20, 6), nullable=True, comment="数量")
    
    # 数量单位
    quantity_unit: Mapped[Optional[str]] = mapped_column(String(50), nullable=True, comment="数量单位")
    
    # 同比增长率(%)
    yoy_growth: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 4), nullable=True, comment="同比增长率(%)")
    
    # 累计金额（亿美元）
    cumulative_amount_usd: Mapped[Optional[Decimal]] = mapped_column(Numeric(20, 4), nullable=True, comment="累计金额(亿美元)")
    
    # 累计同比增长率(%)
    cumulative_yoy: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 4), nullable=True, comment="累计同比增长率(%)")
    
    # 频率：月度, 季度, 年度
    frequency: Mapped[str] = mapped_column(String(20), nullable=False, comment="频率")
    
    # 发布日期
    publish_date: Mapped[Optional[date]] = mapped_column(Date, nullable=True, comment="发布日期")
    
    __table_args__ = (
        UniqueConstraint('period', 'trade_type', 'commodity_code', 'country_code', 
                        name='uk_trade_data_period_type_commodity_country'),
        Index('idx_trade_data_period', 'period'),
        Index('idx_trade_data_type', 'trade_type'),
        Index('idx_trade_data_commodity', 'commodity_code'),
        Index('idx_trade_data_country', 'country_code'),
        Index('idx_trade_data_frequency', 'frequency'),
        # 分区索引
        Index('idx_trade_data_partition_date', 'partition_date'),
    )
    
    def __repr__(self) -> str:
        return f"<TradeData(period={self.period}, trade_type={self.trade_type}, amount_usd={self.amount_usd})>"


class EnergyData(BaseFinancialModel, PartitionMixin):
    """
    能源数据模型
    存储能源生产、消费、价格等相关数据
    """
    __tablename__ = "energy_data"
    
    # 统计期间
    period: Mapped[date] = mapped_column(Date, nullable=False, comment="统计期间")
    
    # 能源类型：原油, 天然气, 煤炭, 电力等
    energy_type: Mapped[str] = mapped_column(String(50), nullable=False, comment="能源类型")
    
    # 数据类型：产量, 消费量, 库存, 价格, 进口量, 出口量
    data_type: Mapped[str] = mapped_column(String(20), nullable=False, comment="数据类型")
    
    # 数值
    value: Mapped[Optional[Decimal]] = mapped_column(Numeric(20, 6), nullable=True, comment="数值")
    
    # 单位
    unit: Mapped[Optional[str]] = mapped_column(String(50), nullable=True, comment="单位")
    
    # 同比增长率(%)
    yoy_growth: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 4), nullable=True, comment="同比增长率(%)")
    
    # 环比增长率(%)
    mom_growth: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 4), nullable=True, comment="环比增长率(%)")
    
    # 地区代码
    region_code: Mapped[Optional[str]] = mapped_column(String(20), nullable=True, comment="地区代码")
    
    # 地区名称
    region_name: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, comment="地区名称")
    
    # 频率：日度, 周度, 月度, 季度, 年度
    frequency: Mapped[str] = mapped_column(String(20), nullable=False, comment="频率")
    
    # 发布机构
    publisher: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, comment="发布机构")
    
    # 发布日期
    publish_date: Mapped[Optional[date]] = mapped_column(Date, nullable=True, comment="发布日期")
    
    __table_args__ = (
        UniqueConstraint('period', 'energy_type', 'data_type', 'region_code', 
                        name='uk_energy_data_period_type_data_region'),
        Index('idx_energy_data_period', 'period'),
        Index('idx_energy_data_energy_type', 'energy_type'),
        Index('idx_energy_data_data_type', 'data_type'),
        Index('idx_energy_data_region', 'region_code'),
        Index('idx_energy_data_frequency', 'frequency'),
        # 分区索引
        Index('idx_energy_data_partition_date', 'partition_date'),
    )
    
    def __repr__(self) -> str:
        return f"<EnergyData(period={self.period}, energy_type={self.energy_type}, data_type={self.data_type}, value={self.value})>"


class RealEstateData(BaseFinancialModel, PartitionMixin):
    """
    房地产数据模型
    存储房地产相关数据，如房价、销售面积、投资等
    """
    __tablename__ = "real_estate_data"
    
    # 统计期间
    period: Mapped[date] = mapped_column(Date, nullable=False, comment="统计期间")
    
    # 数据类型：房价, 销售面积, 销售金额, 投资, 新开工面积, 竣工面积等
    data_type: Mapped[str] = mapped_column(String(50), nullable=False, comment="数据类型")
    
    # 房屋类型：住宅, 商业, 办公, 工业等
    property_type: Mapped[Optional[str]] = mapped_column(String(50), nullable=True, comment="房屋类型")
    
    # 数值
    value: Mapped[Optional[Decimal]] = mapped_column(Numeric(20, 6), nullable=True, comment="数值")
    
    # 单位
    unit: Mapped[Optional[str]] = mapped_column(String(50), nullable=True, comment="单位")
    
    # 同比增长率(%)
    yoy_growth: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 4), nullable=True, comment="同比增长率(%)")
    
    # 环比增长率(%)
    mom_growth: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 4), nullable=True, comment="环比增长率(%)")
    
    # 累计值
    cumulative_value: Mapped[Optional[Decimal]] = mapped_column(Numeric(20, 6), nullable=True, comment="累计值")
    
    # 累计同比增长率(%)
    cumulative_yoy: Mapped[Optional[Decimal]] = mapped_column(Numeric(10, 4), nullable=True, comment="累计同比增长率(%)")
    
    # 城市代码
    city_code: Mapped[Optional[str]] = mapped_column(String(20), nullable=True, comment="城市代码")
    
    # 城市名称
    city_name: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, comment="城市名称")
    
    # 城市级别：一线, 二线, 三线, 四线
    city_tier: Mapped[Optional[str]] = mapped_column(String(20), nullable=True, comment="城市级别")
    
    # 频率：月度, 季度, 年度
    frequency: Mapped[str] = mapped_column(String(20), nullable=False, comment="频率")
    
    # 发布日期
    publish_date: Mapped[Optional[date]] = mapped_column(Date, nullable=True, comment="发布日期")
    
    __table_args__ = (
        UniqueConstraint('period', 'data_type', 'property_type', 'city_code', 
                        name='uk_real_estate_data_period_type_property_city'),
        Index('idx_real_estate_data_period', 'period'),
        Index('idx_real_estate_data_type', 'data_type'),
        Index('idx_real_estate_data_property_type', 'property_type'),
        Index('idx_real_estate_data_city', 'city_code'),
        Index('idx_real_estate_data_tier', 'city_tier'),
        Index('idx_real_estate_data_frequency', 'frequency'),
        # 分区索引
        Index('idx_real_estate_data_partition_date', 'partition_date'),
    )
    
    def __repr__(self) -> str:
        return f"<RealEstateData(period={self.period}, data_type={self.data_type}, city_name={self.city_name}, value={self.value})>"


# 导出所有宏观经济相关模型
__all__ = [
    'MacroEconomicIndicator',
    'MonetaryPolicy',
    'FiscalData',
    'TradeData',
    'EnergyData',
    'RealEstateData',
]